package com.csw.spark

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Demo11Join {
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf()
      .setAppName("join")
      .setMaster("local")

    val sc: SparkContext = new SparkContext(conf)

    val nameRDD: RDD[(String, String)] = sc.parallelize(List(("001", "张三"), ("002", "李四"), ("003", "王五"), ("004", "小伟")))

    val ageRDD: RDD[(String, Int)] = sc.parallelize(List(("001", 23), ("002", 24), ("003", 25)))

    /**
      * join：默认是inner join  两个rdd都必须是kv格式
      */

    val joinRDD: RDD[(String, (String, Int))] = nameRDD.join(ageRDD)

    //join之后整理数据

    val mapRDD: RDD[(String, String, Int)] = joinRDD.map(kv => {
      val id: String = kv._1
      val name: String = kv._2._1
      val age: Int = kv._2._2
      (id, name, age)
    })

    //如果rdd结构复杂，可以通过case简写，提高可读性
    val mapcaseRDD: RDD[(String, String, Int)] = joinRDD.map {
      //一行一行对rdd的数据进行匹配(匹配类型)
      case (id: String, (name: String, age: Int)) => {
        (id, name, age)
      }
    }

    //    mapcaseRDD.foreach(println)

    val leftJoinRDD: RDD[(String, (String, Option[Int]))] = nameRDD.leftOuterJoin(ageRDD)

    val mapleftRDD: RDD[Unit] = leftJoinRDD.map(kv => {
      val id: String = kv._1
      val name: String = kv._2._1
      val age: Int = kv._2._2.getOrElse(0)
      (id, name, age)


    })
    //leftjoin简写
    val leftjoinmapRDD: RDD[(String, String, Int)] = leftJoinRDD.map {
      //匹配关联成功的数据
      case (id: String, (name: String, Some(age))) => {
        (id, name, age)
      }
      //匹配没有关联上的数据
      case (id: String, (name: String, None)) => {
        (id, name, 0)
      }
    }

    leftjoinmapRDD.foreach(println)
  }
}
